﻿#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Serialization;
/// <summary>
/// 逻辑代码
/// </summary>
public partial class ESF_Logic
{
    #region ClearCacheXmlCatalog 清除缓存Xml目录
    /// <summary>
    /// 清除缓存Xml目录
    /// </summary>
    public static void ClearCacheXmlCatalog()
    {
        mESF_BuildXmlAsset_CacheXmlCatalogMaping.Clear();
    }
    #endregion

    #region ClearUnusedXmlCatalog 清除未使用的Xml目录
    /// <summary>
    /// 清除未使用的Xml目录
    /// </summary>
    public static void ClearUnusedXmlCatalog()
    {        
        Type btype = typeof(AbsESF_EditorBuildAsset);
        List<Type> builds = ESF_Utility.GetTypes((t) => { return t.IsGenericType && t.Name.Contains(ESF_BuildXmlAsset_CacheXmlCatalog_GlobalVariable.cInstanceTypeName); });
        List<string> usefiles = new List<string>();
        string folder = string.Empty;
        if (builds != null && builds.Count > 0)
        {
            Type t = builds[0];
            PropertyInfo[] pfs = typeof(ESF_Logic).GetProperties(BindingFlags.Public | BindingFlags.Static);
            if (pfs != null && pfs.Length > 0)
            {
                foreach (var p in pfs)
                {
                    if (t.GetGenericTypeDefinition().ESF_IsTypeOrSubTypeOf(t))
                    {
                        AbsESF_EditorBuildAsset ea = p.GetValue(null) as AbsESF_EditorBuildAsset;
                        folder = ea.directory;
                        usefiles.Add(ea.filePath.ToLower().Trim());
                    }
                }

                string[] files = Directory.GetFiles(folder, $"*{enESF_UnityFileExt.Xml.ESF_FirstAttribute<ESF_FileExtAttribute>().ext}");
                if (files != null && files.Length > 0)
                {
                    foreach (var p in files)
                    {
                        if (!usefiles.Contains(p.ESF_TransPathSeparatorCharToUnityChar().ToLower().Trim()))
                        {
                            File.Delete(p);
                        }
                    }
                }
            }
        }
        ESF_Utility.ExecuteMenuAssetsRefresh();
    }
    #endregion

    #region GetNearEditorRelativePath 获得最近的Editor相对路径
    /// <summary>
    /// 获得最近的Editor相对路径
    /// </summary>
    /// <returns>最近的Editor相对路径</returns>
    public static string GetNearEditorRelativePath()
    {
        return ESF_Utility.GetNearEditorRelativePath(ESF_Utility.TraceCaller_SourceFilePath());
    }
    #endregion

    #region GetNearEditorFullPath 获得最近的Editor绝对路径
    /// <summary>
    /// 获得最近的Editor绝对路径
    /// </summary>
    /// <returns>最近的Editor相对路径</returns>
    public static string GetNearEditorFullPath()
    {
        return ESF_Utility.GetNearEditorFullPath(ESF_Utility.TraceCaller_SourceFilePath());
    }
    #endregion    

    #region GetCacheXmlCatalog 获得缓存Xml目录
    /// <summary>
    /// 缓存目录映射
    /// </summary>
    static Dictionary<int, object> mESF_BuildXmlAsset_CacheXmlCatalogMaping = new Dictionary<int, object>();
    /// <summary>
    /// 缓存目录路径
    /// </summary>
    static readonly string mCacheXmlCatalogFolder = $"{GetNearEditorRelativePath()}Xml";
    /// <summary>
    /// 缓存目录默认相对目录
    /// </summary>
    const string mCacheXmlCatalogRelativeCallerFilePath = "CacheXmlCatalog";
    /// <summary>
    /// 获得缓存Xml目录
    /// </summary>
    /// <param name="_catalog">目录</param>
    /// <param name="_fileName">文件名称</param>
    /// <param name="_directoryRelativeCallerFilePath">相对目录</param>
    /// <returns>缓存Xml目录</returns>
    public static ESF_BuildXmlAsset_CacheXmlCatalog<X> GetCacheXmlCatalog<X>(
        ESF_enCacheXmlCatalog _catalog, string _fileName = "", string _directoryRelativeCallerFilePath = mCacheXmlCatalogRelativeCallerFilePath)
        where X : AbsESF_Xml, new()
    {
        int key = $"{_catalog}_{_fileName}_{typeof(X).FullName}_{_directoryRelativeCallerFilePath}".ESF_UniqueHashCode();
        object result = null;
        if (!mESF_BuildXmlAsset_CacheXmlCatalogMaping.TryGetValue(key, out result))
        {
            result = new ESF_BuildXmlAsset_CacheXmlCatalog<X>(_catalog, _fileName, Path.Combine(mCacheXmlCatalogFolder, _directoryRelativeCallerFilePath));
            mESF_BuildXmlAsset_CacheXmlCatalogMaping.Add(key, result);
            ESF_Utility.ExecuteMenuAssetsRefresh();
        }
        return (ESF_BuildXmlAsset_CacheXmlCatalog<X>)result;
    }
    #endregion

    #region GetResxTempleteFilePath 获得模版文件路径
    /// <summary>
    /// ResxTemplete枚举脚本
    /// </summary>
    static readonly ESF_BuildTextAsset mResxTempleteEnumScript = new ESF_BuildTextAsset("ESF_enResxTempleteFile", Path.Combine(GetNearEditorFullPath(), "ResxTemplete"), enESF_UnityFileExt.CS, "");
    #endregion

    #region GetProjectSettingMenuItem 获取工程设定菜单
    /// <summary>
    /// 获取工程设定菜单
    /// Key:菜单方法
    /// Value:菜单属性
    /// </summary>
    /// <returns>工程设定菜单</returns>
    public static Dictionary<MethodInfo, ESF_ProjectSettingMenuItemAttribute> GetProjectSettingMenuItem()
    {
        Dictionary<MethodInfo, ESF_ProjectSettingMenuItemAttribute> result = new Dictionary<MethodInfo, ESF_ProjectSettingMenuItemAttribute>();
        Type pt = typeof(AbsESF_EditorMenuItem);
        List<Type> types = ESF_Utility.GetTypes((t) => { return t.ESF_IsSubTypeOf(pt); });
        ESF_ProjectSettingMenuItemAttribute attr = null;
        foreach (Type t in types)
        {
            MethodInfo[] ms = t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            if (ms != null && ms.Length > 0)
            {
                foreach (MethodInfo m in ms)
                {
                    attr = m.ESF_FirstAttribute<ESF_ProjectSettingMenuItemAttribute>();
                    if (attr != null)
                    {
                        result.Add(m, attr);
                    }
                }
            }
        }
        return result;
    }
    #endregion

    #region GetProjectQuickButton 获取工程快捷按钮
    /// <summary>
    /// 获取工程快捷按钮
    /// Key:按钮方法
    /// Value:按钮属性
    /// </summary>
    /// <returns>工程快捷按钮</returns>
    public static Dictionary<MethodInfo, ESF_ProjectQuickButtonAttribute> GetProjectQuickButton()
    {
        Dictionary<MethodInfo, ESF_ProjectQuickButtonAttribute> result = new Dictionary<MethodInfo, ESF_ProjectQuickButtonAttribute>();
        List<Type> types = ESF_Utility.GetTypes();
        ESF_ProjectQuickButtonAttribute attr = null;
        foreach (Type t in types)
        {
            MethodInfo[] ms = t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            if (ms != null && ms.Length > 0)
            {
                foreach (MethodInfo m in ms)
                {
                    attr = m.ESF_FirstAttribute<ESF_ProjectQuickButtonAttribute>();
                    if (attr != null)
                    {
                        result.Add(m, attr);
                    }
                }
            }
        }
        return result;
    }
    #endregion
}
#endif